
package com.ansion.utils.file;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.zip.DataFormatException;

public class StreamUtils {

    @NonNull
    public static byte[] readStream(@NonNull InputStream source, int bytesHint) throws IOException {
        if (bytesHint <= 0) {
            bytesHint = 1024 * 8;
        }
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream(bytesHint);
        copyStream(source, outputStream);
        return outputStream.toByteArray();
    }

    @Nullable
    public static byte[] readStreamSilently(@NonNull InputStream source, int bytesHint) {
        try {
            return readStream(source, bytesHint);
        } catch (IOException e) {
//            LOG.w(e, "%s Failed to read stream", LogTag.TAG_BASE_MISC);
        }
        return null;
    }


    public static String stringFromStream(InputStream is) {
        if (is == null) {
//            LOG.logE(LogTag.TAG_COMMON + "[SU] InputStream is null!");
            return null;
        }

        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                builder.append(line).append('\n');
            }
            return builder.toString();
        } catch (IOException e) {
//            LOG.logE(LogTag.TAG_COMMON + "[SU] error stringFromStream: " + is, e);
        }

        return null;
    }

    public static byte[] byteArrayFromStream(InputStream is) {
        return byteArrayFromStream(is, -1);
    }

    public static byte[] byteArrayFromStream(InputStream is, int softLimit) {
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[2048];
            int total = 0;
            int read = 0;

            do {
                read = is.read(buffer);
                if (read > 0) {
                    baos.write(buffer, 0, read);
                    total += read;

                    if (softLimit > 0) {
                        if (softLimit < total) {
                            break;
                        }
                    }
                }
            } while (read >= 0);

            return baos.toByteArray();
        } catch (IOException e) {
//            LOG.logE(LogTag.TAG_COMMON + "[SU] error byteArrayFromStream: " + is, e);
            return null;
        }
    }

    @SuppressWarnings("UnusedReturnValue")
    public static long copyStream(@NonNull InputStream source, @NonNull OutputStream target) throws IOException {
        byte[] buffer = new byte[1024 * 8];
        int read;
        long totalBytes = 0;
        do {
            read = source.read(buffer, 0, buffer.length);
            if (read > 0) {
                target.write(buffer, 0, read);
                totalBytes += read;
            }
        } while (read > 0);
        return totalBytes;
    }
    /***
     * 参照服务器写法，解压缩数据
     * @param raw
     * @return
     * @throws DataFormatException
     */
    public static byte[] unZip(byte[] raw) throws DataFormatException {
        java.util.zip.Inflater inf = new java.util.zip.Inflater(true);
//        byte[] raw = null;
        int length = raw.length;
        int offset = 0;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        inf.setInput(raw, offset, length);
//        CompositeByteBuf ret = Unpooled.compositeBuffer();
        while (true) {
            byte[] buffer = new byte[length * 2];
            int outlen = inf.inflate(buffer);
            if (outlen == 0)
                break;
            baos.write(buffer,0,outlen);
//            ret.addComponent(Unpooled.wrappedBuffer(buffer, 0, outlen));
//            ret.writerIndex(ret.writerIndex() + outlen);
        }
        inf.end();
        return baos.toByteArray();
    }
}
